#!/usr/bin/env python
# -*- coding: utf-8 -*-
#code:utf-8
#
# Copyright(C) 2011 SupDo.com
# Licensed under the GUN License, Version 3.0 (the "License");
# 
# File:        lib
# Author:      KuKei
# Create Date: 2011-04-22
# Description: 自定义库目录
# Modify Date: 2011-04-22

from sd import settings
import memcache
import random
from sd.cms.lib.utility import *
from django.core.cache import cache
from django.core.files.storage import FileSystemStorage

class Params:
    #设置常量参数
    #名字类,这些参数不可修改，因为在模版中直接使用了这些值作为变量名
    THEME = 'theme'
    GLOBALPARAM = 'globalparam'
    PARAMS = 'params'
    POWER = 'power'
    
    #默认值类
    DEFAULTTHEME = 'default'
    
    #验证码session名
    SAFECODE = '_sefecode'
    
    
    ##权限设置
    #访客
    VISITOR = 0
    #用户
    USER = 10
    #管理员
    ADMINISTRATOR = 100
    #创建人
    INITIATOR = 999
    
    #缓存参数
    PARAM = 'param'
    COLUMN = 'column'
    CATALOGS = 'catalogs'
    GLOBAL = 'global'
    ARTICLE = 'article'
    ARTICLELIST = 'arriclelist'
    IMAGE = 'image'
    IMAGELIST = 'imagelist'
    PRODUCT = 'product'
    PRODUCTLIST = 'productlist'
    
    #GlobalParam的kind字典说明
    GPView = 10;
    GPArticle = 130;
    GPProduct = 140;
    GPLinks = 200;

    #初始化函数
    def __init__(self):
        pass

class Result:
    def __init__(self, flag=False, msg='', html='', toUrl='/', sleep=3):
        self.flag = flag
        self.msg = msg
        self.html = html
        self.toUrl = toUrl
        self.sleep = sleep
    
    def tojson(self):
        return {'flag':self.flag,'msg':self.msg,'html':self.html,'toUrl':self.toUrl,'sleep':self.sleep}
    
class Pager:
    def __init__(self, request, kind='', showPages=None, pageSize=None):
        self.request = request
        self.kind = kind
        self.totalPages = 0
        self.currentPages = 1
        self.globalparams = SDMemCache().getBase(Params.GLOBAL)[1]
        self.showPages = showPages if showPages else self.getShowPages()
        self.pageSize = pageSize if pageSize else self.getPageSize()
        self.totalSize = 0
        self.startSize = 0
        self.endSize = 0
        self.urlPath = ''
        self.pageList = []
        self.initPage()
        
    def initPage(self):
        self.urlPath = self.request.META['PATH_INFO']
        if self.request.GET.has_key('cPages'):
            self.currentPages = int(self.request.GET['cPages'])
        elif(self.currentPages<1):
            self.currentPages = 1
        self.startSize = (self.currentPages-1)*self.pageSize
        self.endSize = self.currentPages*self.pageSize
        
    def getEndSize(self):
        return min(self.endSize, self.totalSize)
        
    def getPageSize(self):
        try:
            return int(self.globalparams[Params.GPView][self.kind+'PageSize'])
        except Exception,ex:
            return 10
    
    def getShowPages(self):
        try:
            return int(self.globalparams[Params.GPView][self.kind+'ShowPages']) if self.globalparams[Params.GPView].has_key(self.kind+'ShowPages') else int(self.globalparams[Params.GPView]['ShowPages'])
        except Exception,ex:
            return 10
    
    def getPagesInt(self, pNum, cNum):
        if (pNum%cNum)==0:
            return pNum/cNum
        else:
            return pNum/cNum+1
    
    def getPageList(self):
        self.totalPages = self.getPagesInt(self.totalSize, self.pageSize)
        endNum = 1
        pageNum = 1
        if(self.totalPages<=self.showPages):
            pageNum = 1
            endNum = self.totalPages
        else:
            if(self.currentPages <= self.getPagesInt(self.showPages, 2)):
                pageNum = 1
                endNum = self.showPages;
            elif((self.currentPages + self.getPagesInt(self.showPages, 2))>=self.totalPages):
                pageNum = self.totalPages - self.showPages + 1
                endNum = self.totalPages
            else:
                pageNum = self.currentPages - self.getPagesInt(self.showPages, 2) + 1
                endNum = self.currentPages + self.showPages - self.getPagesInt(self.showPages, 2)

        while (pageNum <= endNum):
            self.pageList.append({'pageNum':pageNum})
            pageNum += 1
        
        return self
    
#自定义的文件存储系统
class SDFileSystemStorage(FileSystemStorage):
    def __init__(self, path):
        FileSystemStorage.__init__(self, settings.MEDIA_ROOT+'/'+path+'/', settings.MEDIA_URL+'/'+path+'/')

class SDMemCache:
    project_prefix = settings.PROJECT_NAME
    data_prefix = 'data'
    page_prefix = 'page'
    base_prefix = 'base'
    theme_prefix = 'theme'
    cache_time = None;
    ns = None
    ns2 = None
    mc = None
    def __init__(self):
        self.cache_time = 24*60*60
        self.mc = cache
        
    #===========================================================================
    # 用版本号模拟memcache的命名空间管理
    # 存在二级命名空间
    #===========================================================================
    def getNS(self):
        ns_key = self.project_prefix+'_ns'
        self.ns = cache.get(ns_key)
        if not self.ns:
            cache.set(ns_key, random.randint(1, 10000), self.cache_time)
        self.ns =  cache.get(ns_key)
        return self.ns
    
    def flushNS(self):
        ns_key = self.project_prefix+'_ns'
        self.ns = cache.get(ns_key)
        if self.ns:
            cache.incr(ns_key, 1)
        else:
            cache.set(ns_key, random.randint(1, 10000), self.cache_time)
        
    #===========================================================================
    # 对于二级命名空间，不同的模型有不同的命名空间版本号
    #===========================================================================
    def getNS2(self, key):
        if key in (Params.ARTICLELIST, Params.IMAGELIST, Params.PRODUCTLIST, Params.PRODUCT, Params.PARAM, Params.COLUMN, Params.CATALOGS):
            ns2_key = self.project_prefix+'_ns2_'+key
            self.ns2 = cache.get(ns2_key)
            if not self.ns2:
                cache.set(ns2_key, random.randint(1, 10000), self.cache_time)
            self.ns2 =  cache.get(ns2_key)
        else:
            self.ns2 = 1
        return self.ns2
    
    def flushNS2(self, key):
        ns2_key = self.project_prefix+'_ns2_'+key
        self.ns2 = cache.get(ns2_key)
        if self.ns2:
            cache.incr(ns2_key, 1)
        else:
            cache.set(ns2_key, random.randint(1, 10000), self.cache_time)        
        
    def flushPage(self, prefix, key):
        cache.delete(self.getLongKey(self.page_prefix, prefix, key))
        
    def flushData(self, prefix, val=None):
        if val:
            cache.replace(self.getLongKey(self.data_prefix, prefix, None), val, self.cache_time)
        else:
            cache.delete(self.getLongKey(self.data_prefix, prefix, None))
            
    def flushBase(self, key):
        cache.delete(self.getLongKey(self.base_prefix, key, None))
        
    def getBase(self, key):
        baseKey = self.getLongKey(self.base_prefix, key, None)
        return self.get(baseKey)
    #=======================================================================
    # memcache的key全名格式为：项目名_一级命名空间名_二级命名空间名_类型名_具体数据名(_编号)
    #=======================================================================
    def getLongKey(self, kind, key, subkey):
        return '%s_%s_%s_%s_%s_%s'%(self.project_prefix, self.getNS(), self.getNS2(key), kind, key, nvl(subkey,1))
    
        
    def set(self, key, val, time=cache_time):
        return cache.set(key, val, time)
        
    def get(self, key):
        return cache.get(key)
    
    def replace(self, key, val):
        return cache.replace(self.prefix+key, val, self.cache_time)
    
    def replaceData(self, key, val):
        return cache.replace(self.data_prefix+key, val, self.cache_time)
    
    def delete(self, key):
        return cache.delete(key)
    
    def incr(self, key, delta=1):
        return cache.incr(key, delta)

    def decr(self, key, delta=1):
        return cache.decr(key, delta)
    
